﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using agree.schema;

using alib.BitArray;
using alib.Collections;
using alib.Collections.ReadOnly;
using alib.Combinatorics;
using alib.Debugging;
using alib.Enumerable;
using alib.Reflection;
using alib.String;

namespace agree.transfer_prototype
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// 
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	[DebuggerDisplay("{ToString(),nq}")]
	public struct NodePtr
	{
		public NodePtr(rel_base rel, int arg_ix) { this.rel = rel; this.arg_ix = arg_ix; }
		public rel_base rel;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public int arg_ix;
		//public static implicit operator type_base(NodePtr np) { return np.rel.values[np.arg_ix]; }

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public type_base node_type { get { return rel.values[arg_ix]; } }

		public bool Subsumes(NodePtr other)
		{
			return this.node_type == null || this.node_type.Subsumes(other.node_type);
		}

		public bool try_set_type(type_base t)
		{
			return unify_into(ref rel.values[arg_ix], t);
		}

		static bool unify_into(ref type_base t1, type_base t2)
		{
			type_base result;
			if ((result = __xfer_ext.Unify(t1, t2)) == null)
				return false;
			t1 = result;
			return true;
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public String feat { get { return rel_base.rgfeat[arg_ix]; } }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public String ShortInf { get { return String.Format("{0,-4}  {1}", feat, node_type); } }

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public String RelFeatInf { get { return String.Format("{0}/{1}", rel.Id, feat); } }

		public override String ToString() { return String.Format("{0}: {1}", rel.Id, ShortInf); }
	};
}